@tool
class_name DataItem
extends Resource


## 先导出的属性先赋值。若属性对赋值的顺序有要求，则一定要注意属性导出的先后顺序。



@export var max_value: float:
    set(val):
        if val < min_value:
            val = min_value
            base_value = val
        elif val < base_value:
            base_value = val
        
        if max_value == val: return
        var old := max_value
        max_value = val
        max_value_changed.emit(old, max_value)


@export var min_value: float:
    set(val):
        if val > max_value:
            val = max_value
            base_value = val
        elif val > base_value:
            base_value = val
        
        if min_value == val: return
        var old := min_value
        min_value = val
        min_value_changed.emit(old, min_value)


@export var base_value: float:
    set(val):
        val = clampf(val, min_value, max_value)
        if base_value == val: return
        var old := base_value
        base_value = val
        base_value_changed.emit(old, base_value)
        value_changed.emit(clampf(old + _total_modified_value, min_value, max_value), 
                            clampf(base_value + _total_modified_value, min_value, max_value))
        
        resource_name = "%.2f" % base_value


## 只通过该属性获取值，对该属性进行赋值无效
var value: float:
    get:
        return clampf(base_value + _total_modified_value, min_value, max_value)

var _total_modified_value: float = 0

func add_modifier(modifier: float) -> void:
    if is_zero_approx(modifier): return
    var old := value
    _total_modified_value += modifier
    value_changed.emit(old, value)


func clear_modifiers() -> void:
    if is_zero_approx(_total_modified_value): return
    var old := value
    _total_modified_value = 0
    value_changed.emit(old, value)


func apply_modifiers() -> void:
    base_value = value
    clear_modifiers()


signal base_value_changed(ov: float, nv: float)
signal min_value_changed(ov: float, nv: float)
signal max_value_changed(ov: float, nv: float)
signal value_changed(ov: float, nv: float)


func _init() -> void:
    resource_local_to_scene = true
    resource_name = "%.2f" % base_value


func _to_string() -> String:
    return "base value: %.2f, min value: %.2f, max value: %.2f" % [base_value, min_value, max_value]


func int_value() -> int:
    return int(value)


func roundi_value() -> int:
    return roundi(value)


func floori_value() -> int:
    return floori(value)


func equal_value(val: float) -> bool:
    return is_equal_approx(value, val)


## 创建DataItem的静态方法
static func create(base_val: float, min_val: float, max_val: float) -> DataItem:
    var item := DataItem.new()
    item.max_value = max_val
    item.min_value = min_val
    item.base_value = base_val
    return item
    
